package demoMod.gdxform.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import demoMod.gdxform.abstracts.Container;
import demoMod.gdxform.interfaces.Element;
import demoMod.gdxform.interfaces.KeyboardEventSubscriber;
import demoMod.gdxform.interfaces.MouseEventSubscriber;

import java.util.List;
import java.util.stream.Collectors;

public class GMenuBar extends Container<GMenuBar.GMenuBarItem> implements MouseEventSubscriber, KeyboardEventSubscriber {
    @Override
    public void update() {
        int index = 0;
        for (GMenuItem gMenuItem : getElements()) {
            gMenuItem.setX(index * Math.max(Gdx.graphics.getWidth() * 0.03F, 48.0F));
            index++;
        }
        super.update();
    }

    @Override
    public void addElement(GMenuBarItem element) {
        element.setPriority(getElements().size());
        element.setWidth(Math.max(Gdx.graphics.getWidth() * 0.03F, 48.0F));
        element.setHeight(this.getHeight());
        element.setX(Math.max(Gdx.graphics.getWidth() * 0.03F, 48.0F) * element.getPriority());
        element.setY(0);
        super.addElement(element);
    }

    @Override
    public void removeElement(Element element) {
        super.removeElement(element);
        int index = 0;
        for (GMenuItem gMenuItem : getElements()) {
            gMenuItem.setPriority(index);
            gMenuItem.setX(Math.max(index * Gdx.graphics.getWidth() * 0.03F, 48.0F));
            index++;
        }
    }

    @Override
    public float getX(boolean isAbsolute) {
        return getParent() == null ? 0 : getParent().getX(isAbsolute);
    }

    @Override
    public float getY(boolean isAbsolute) {
        return getParent() == null ? Gdx.graphics.getHeight() - getHeight() : super.getY(isAbsolute);
    }

    @Override
    public float getWidth() {
        return getParent() == null ? Gdx.graphics.getWidth() : getParent().getWidth();
    }

    @Override
    public boolean keyDown(int keyCode) {
        if (Gdx.input.isKeyPressed(Input.Keys.ALT_LEFT) || Gdx.input.isKeyPressed(Input.Keys.ALT_RIGHT)) {
            for (GMenuItem gMenuItem : getElements()) {
                if (gMenuItem.keyDown(keyCode)) {
                    gMenuItem.setSelected(true);
                    for (GMenuItem item1 : getElements()) {
                        if (item1 != gMenuItem) {
                            item1.setSelected(false);
                        }
                    }
                    return true;
                } else {
                    gMenuItem.setSelected(false);
                }
            }
        }
        return false;
    }

    @Override
    public boolean keyUp(int keyCode) {
        return false;
    }

    @Override
    public boolean keyTyped(char key) {
        return false;
    }

    @Override
    public boolean clickDown(int screenX, int screenY, int button) {
        for (GMenuBarItem item : getElements()) {
            if (item.clickDown(screenX, screenY, button)) {
                item.setSelected(true);
                for (GMenuItem item1 : getElements()) {
                    if (item1 != item) {
                        item1.setSelected(false);
                    }
                }
                return true;
            }
        }
        for (GMenuBarItem item : getElements()) {
            item.setSelected(false);
        }
        return false;
    }

    @Override
    public boolean clickUp(int screenX, int screenY, int button) {
        return false;
    }

    @Override
    public boolean mouseDragged(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        List<GMenuBarItem> tmpList = getElements().stream().filter(GMenuItem::isSelected).collect(Collectors.toList());
        if (screenX >= getX(true) && screenX <= getX(true) + getWidth() &&
                Gdx.graphics.getHeight() - screenY >= getY(true) && Gdx.graphics.getHeight() - screenY <= getY(true) + getHeight() && enabled()
                && !tmpList.isEmpty()) {
            for (GMenuItem gMenuItem : getElements()) {
                if (gMenuItem.mouseMoved(screenX, screenY)) {
                    gMenuItem.setSelected(true);
                    for (GMenuItem item1 : getElements()) {
                        if (item1 != gMenuItem) {
                            item1.setSelected(false);
                        }
                    }
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }

    @Override
    public boolean moveToElementBorder(Element element) {
        return false;
    }

    public static class GMenuBarItem extends GMenuItem {
        private float x;
        private float width;

        public GMenuBarItem(float width, float height, String text, BitmapFont font) {
            super(width, height, text, font);
            setIconWidth(3);
            this.subMenuWaitTimer = 0.0F;
        }

        @Override
        public void render(SpriteBatch sb) {
            sb.setColor(Color.WHITE.cpy());
            if (this.bgTexture != null) {
                sb.draw(this.bgTexture, getX(true), getY(true), getWidth(), getHeight());
            }
            if (this.isSelected() && this.selectedBgTexture != null) {
                sb.draw(this.selectedBgTexture, getX(true), getY(true), getWidth(), getHeight());
            }
            if (this.icon != null) {
                sb.draw(this.icon, getX(true), getY(true), this.iconWidth, this.iconWidth);
            }
            if (this.isSelected()) {
                this.label.setColor(this.selectedTextColor);
            } else {
                this.label.setColor(this.textColor);
            }
            if (!this.enabled()) {
                this.label.setColor(this.disabledTextColor);
            }
            this.label.render(sb);
        }

        @Override
        public void setX(float x) {
            this.x = x;
        }

        @Override
        public float getX(boolean isAbsolute) {
            return getParent() == null ? x : getParent().getX(isAbsolute) + x;
        }

        @Override
        public float getY(boolean isAbsolute) {
            return getParent() == null ? 0 : getParent().getY(isAbsolute);
        }

        @Override
        public void setWidth(float width) {
            this.width = width;
        }

        @Override
        public float getWidth() {
            return this.width;
        }
    }
}
